//#import <Foundation/Foundation.h>
//#import <AppKit/AppKit.h>
//#import <CoreData/CoreData.h>

#include "TextureLoad.h"
//#include <UIKit/UIImage.h>

void * LoadFile(const char *fileName, unsigned long *size = NULL) {
	FILE *f = fopen (fileName, "rb");
	if(0 == f) {
		printf("file not found %s\n", fileName);
		return 0;
	}
	
	// Get file size
	long curr_pos = ftell (f), fsize = 0;
	fseek (f, 0L, SEEK_END);
	fsize = ftell (f);
	fseek (f, curr_pos, SEEK_SET);
	
	// Get memory
	void *ptr = malloc(fsize);
	if(!ptr)
	{
		fclose (f);
		printf("not enougth memory\n");
		return 0;
	}
	
	if (fsize != fread (ptr, 1, fsize, f) ) {
		fclose (f);
		free(ptr);
		printf("can't read data from file\n");
		return 0;
	}
	
	fclose (f);
	if(size) *size = fsize;
	return ptr;
}

GLuint TextureLoad(const char *fileName, float &outWidth, float &outHeight) {
	void *data = 0;
	unsigned long size = 0;
	
    data = LoadFile(fileName, &size);
    if (!data) {
        return NULL;   
    }
	
	NSAutoreleasePool *pool = [NSAutoreleasePool new];
	
	NSData *memData = [[NSData alloc] initWithBytes:data length:size];	
	CGImageRef bitmap = [UIImage imageWithData:memData].CGImage;
	if (0 == bitmap)
	{	
		printf("Texture_Load: Can't create image\n");
		[memData release];
		if (!size) {
            free(data);
        }
		[pool release];
		return 0;
	}
	
	GLint internalFormat = 0;
	GLenum format = 0, type = 0;
	int width = outWidth = CGImageGetWidth(bitmap);
    int height = outHeight = CGImageGetHeight(bitmap);	
	int bitsPerPixel = CGImageGetBitsPerPixel(bitmap);
	CGImageAlphaInfo aInfo = CGImageGetAlphaInfo(bitmap);
	
	CFDataRef bitmapDataCG = CGDataProviderCopyData(CGImageGetDataProvider(bitmap));
	const UInt8 *bitmapDataPtr = CFDataGetBytePtr (bitmapDataCG);
	
	if (bitsPerPixel < 16 || bitsPerPixel > 32)
	{	
		printf("Texture_Load: Invalid BPP");
		[memData release];
		CFRelease(bitmapDataCG);
		if(!size) {
			free(data);		
        }
		[pool release];
		return 0;
	}
	
	switch (bitsPerPixel)
	{
		case 16:
			if (aInfo != kCGImageAlphaNone) {
				internalFormat = GL_RGBA;
				format = GL_RGBA; type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
			} else {	
				internalFormat = GL_RGB;
				format = GL_RGB; type = GL_UNSIGNED_SHORT_5_6_5;
			}
			break;
			
		case 24:
			internalFormat = GL_RGB; format = GL_RGB; type = GL_UNSIGNED_BYTE;			
			break;
			
		case 32:
			if (aInfo != kCGImageAlphaNone) {
				internalFormat = GL_RGBA;
				format = GL_RGBA; type = GL_UNSIGNED_BYTE;
			} else {	
				internalFormat = GL_RGBA;
				format = GL_RGBA; type = GL_UNSIGNED_BYTE;
			}
			break;
		case 64:
			if (aInfo != kCGImageAlphaNone) {
				internalFormat = GL_RGBA;
				format = GL_RGBA; type = GL_UNSIGNED_SHORT;
			} else {	
				internalFormat = GL_RGBA;
				format = GL_RGBA; type = GL_UNSIGNED_SHORT;
			}
			break;
	}
	
	// Create texture
	GLuint name;
	glGenTextures(1, &name);	
	if (GL_INVALID_VALUE == name) {	
		printf("Can't create texture");
		[memData release];
		CFRelease(bitmapDataCG);
		if(!size) {
			free(data);
		}
		[pool release];
		return 0;
	}
    
	glBindTexture (GL_TEXTURE_2D, name);	
	// Texture option
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    glTexImage2D (GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, bitmapDataPtr);
		
	// Release data
	[memData release];
	CFRelease(bitmapDataCG);
	if (!size) {
		free(data);
	}
    
	[pool release];
    printf("file loaded %s\n", fileName);
	return name;
}

char szAppPath[1024];

const char * MakePath(const char *fileName) {
     
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    NSBundle *mainBundle = [NSBundle mainBundle];
    NSString *res = [mainBundle resourcePath];
    [res getCString:szAppPath maxLength:sizeof(szAppPath) encoding:NSASCIIStringEncoding];
    strcat (szAppPath, "/");
    strcat (szAppPath, fileName);

    [pool release];
    
    return szAppPath;
}